﻿/* 
	Author	: Dale McKay
	Email	: dalesmckay@gmail.com
	Purpose	: To help locate the best villages for farming.
	Credit	: 
	Todo	:
		* Add spinner when downloading DAT files.
		* Checkbox to ignore your own villages.
		* Checkbox to ignore your own Tribe.
		* Generate a farming script.
		* Make the DIV draggable.
		* Filter by bounding area (coord TL/BR).
		* Allow multiple coords for the radius.
		* Add a clear/reset button.
		* Add a spinner when Finding Farms.
		* Add checkbox to enable/disable each filter option.
	Notes	:
	

	######################
	Client Launcher (live):
	######################
	
javascript:
	var debugEnabled=true;
	var branch='http://dl.dropbox.com/u/25377948/twscripts/';
	(window.main||self).$.getScript(branch+'jquery.tw.farmfinder.js',function(){$.twFarmFinder(branch,debugEnabled);});
	void(0);

____________________________________________________________

Copyright (C) 2011 Dale McKay, all rights reserved
version 1.0, 14 July 2011

This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
This notice may not be removed or altered from any source distribution.
____________________________________________________________
*/

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// $.twFarmFinder(branch,debugEnabled)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
(function($){
	var win=(window.main||self);

	var script={
		id:'{AD48DC2A-89F2-4B3D-A9E3-E9352A763DA0}',
		name:'سكربت البحث عن البربريات',
		version:1.07,
		minGameVersion:7.00,
		author:{
			name:'dalesmckay',
			email:'dalesmckay@gmail.com',
			url:'http://crosstrigger.com'
		},
		credit:'',
		runOnce:true
	};

	// Replace these strings with the correct language translation.
	var config={
		'userMsg':{
		}
	};

	// ........................................................................
	function fnAjax(url,method,params,type,isAsync,callback){
		var payload=null;
		
		$.ajax({
			'async':isAsync,
			'url':url,
			'data':params,
			'dataType':type,
			'type':String(method||'GET').toUpperCase(),
			'error':function(req,status,err){throw(status);},
			'success':function(data,status,req){if(!isAsync){payload=data;}if(typeof(callback)=='function'){callback(data,status,req);}}
		});
		
		if(!isAsync){
			if(typeof(callback)=='function'){
				callback(payload);
			}

			return payload;
		}
	} // fnAjax
	// ........................................................................
	function fnExecute(branch,debugEnabled){try{
		var villagesDAT=null;
		var playersDAT=null;
		var tribesDAT=null;
		var resultCoords=[];
		var detail={};
		
			
		// ........................................................................
		function fnBuildPlayerIDList(playerNames){
			var playerIDList=null;
			
			if(playerNames&&(playerNames.length>0)){
				playerIDList=[];
				
				$.each(playerNames,function(i,e){
					var name=e.toLowerCase();
					
					if(playersDAT[name]){
						playerIDList.push(playersDAT[name].id);
					}
				});
			}
			
			return playerIDList;
		} // fnBuildPlayerIDList
		// ........................................................................
		function fnBuildTribeIDList(tribeTags){
			var tribeIDList=null;
			
			if(tribeTags&&(tribeTags.length>0)){
				tribeIDList=[];

				$.each(tribeTags,function(i,e){
					var tag=e.toLowerCase();
				
					if(tribesDAT[tag]){
						tribeIDList.push(tribesDAT[tag].id);
					}
				});
			}
			
			return tribeIDList;
		} //fnBuildTribeIDList
		// ........................................................................
		function fnFindPlayer(playerID){
			var player=null;
			
			$.each(playersDAT,function(i,e){
				if(e.id==playerID){
					player=e;
					return true;
				}
			});
			
			return player;
		} //fnFindPlayer
		// ........................................................................
		function fnFindTribe(tribeID){
			var tribe=null;
			
			$.each(tribesDAT,function(i,e){
				if(e.id==tribeID){
					tribe=e;
					return true;
				}
			});
			
			return tribe;
		} //fnFindTribe
		// ........................................................................
		function Point(x,y){return {'x':x,'y':y};}
		// ........................................................................
		function Rect(top,left,bottom,right){return {'top':top,'left':left,'bottom':bottom,'right':right};}
		// ........................................................................
		function pointInRect(point,rect){return(point.x>=rect.left&&point.x<=rect.right&&point.y>=rect.top&&point.y<=rect.bottom);}
		// ........................................................................
		function fnIsInsideRegion(coord,mapRegion){
			var tempCoord1=twUtil.extractCoord(coord);
			if(!tempCoord1){
				return false;
			}
			
			var tempCoord2=twUtil.extractCoord(mapRegion.topLeft);
			if(!tempCoord2){
				return false;
			}
			
			var tempCoord3=twUtil.extractCoord(mapRegion.bottomRight);
			if(!tempCoord3){
				return false;
			}
			
			tempCoord1=tempCoord1.split('|');
			tempCoord2=tempCoord2.split('|');
			tempCoord3=tempCoord3.split('|');
			
			// ##################################################################
			// HACK: not sure why I need to reverse the x/y co-ordinates here ???			
			// ##################################################################
			var point=Point(tempCoord1[1],tempCoord1[0]);
			// ##################################################################

			var rect=Rect(tempCoord2[0],tempCoord2[1],tempCoord3[0],tempCoord3[1]);
			
			return pointInRect(point,rect);
		} // fnIsInsideRegion
		// ........................................................................
		function fnFindFarms(){
			twUtil.debug('<span style="color:gray;">CALL: fnFindFarms()...</span>');
			
			var alertMsg='';
			if(!(villagesDAT&&$.trim(JSON.stringify(villagesDAT)))){
				alertMsg+='أنت بحاجة لتحديث ملفات القرى بالعالم';
			}
			if(!(playersDAT&&$.trim(JSON.stringify(playersDAT)))){
				alertMsg+='أنت بحاجة لتحديث ملفات اللاعبين بالعالم';
			}
			if(!(tribesDAT&&$.trim(JSON.stringify(tribesDAT)))){
				alertMsg+='أنت بحاجة لتحديث ملفات القبائل بالعالم ';
			}
			if(alertMsg){
				alert(alertMsg);

				return;
			}
			
			
			var curConfig=fnCurrentConfig();
			
			//NOTE: these fields are not part of the std config (we don't want to save it)
			var srcCoord=twUtil.extractCoord((curConfig.radius>0)?$.trim($('#dsmRadiusCentre').val()):'')||win.game_data.village.coord;
			var	mapRegion={
				topLeft:twUtil.extractCoord($.trim($('#dsmMRTopLeft').val()))||'000|000',
				bottomRight:twUtil.extractCoord($.trim($('#dsmMRBottomRight').val()))||'999|999',
			};
			
			var hasPlayerFilter=!!$.trim($('#dsmPlayers').val());
			var hasTribeFilter=!!$.trim($('#dsmTribes').val());
					
			// Build PlayerID List.
			// TODO...
			var playerIDs=fnBuildPlayerIDList(curConfig.players);
			
			//Build TribeID List.
			// TODO...
			var tribeIDs=fnBuildTribeIDList(curConfig.tribes);
			
			// Reset the co-ordinates.
			resultCoords=[];
			
			$.each(villagesDAT,function(i,e){
				var player=null;
				var tribe=null;
				// Ignore your own villages.
				if(e.ownerID==win.game_data.player.id){
					// TODO: allow your own villages.
					return true;
				}

				// Min Points Filter.
				if((curConfig.minPoints>=0)&&(e.points<curConfig.minPoints)){
					return true;
				}
				
				// Max Points Filter.
				if((curConfig.maxPoints>=0)&&(e.points>curConfig.maxPoints)){
					return true;
				}
				
				// Radius Filter.
				if((curConfig.radius>0)&&srcCoord&&(twUtil.fields(srcCoord,e.coord)>curConfig.radius)){
					return true;
				}
				
				// Map Region Filter.
				if(!fnIsInsideRegion(e.coord,mapRegion)){
					return true;
				}
				
				// Continent Filter.
				if(curConfig.continents&&(curConfig.continents.length>0)&&(curConfig.continents.indexOf(e.continent)<0)){
					return true;
				}

				// Barb Filter.
				if(curConfig.barbsOnly){
					if(!e.ownerID){
						resultCoords.push(e.coord);
						detail[e.coord]={village:e,player:null,tribe:null};
						return true;
					}
				}
				else{
					player=fnFindPlayer(e.ownerID);
					tribe=player?fnFindTribe(player.tribeID):null;
					
					// Player Filter.
					if(hasPlayerFilter&&playerIDs&&(playerIDs.indexOf(e.ownerID)>=0)){
						resultCoords.push(e.coord);
						detail[e.coord]={village:e,player:player,tribe:tribe};
						return true;
					}
					
					// Tribe Filter.
					if(hasTribeFilter&&tribeIDs){
						if(player&&player.tribeID&&(tribeIDs.indexOf(player.tribeID)>=0)){					
							resultCoords.push(e.coord);
							detail[e.coord]={village:e,player:player,tribe:tribe};
							return true;
						}
					}
					
					if(!hasPlayerFilter&&!hasTribeFilter){
						resultCoords.push(e.coord);
						detail[e.coord]={village:e,player:player,tribe:tribe};
						return true;
					}
				}				
			});
			
			// Sort the co-ordinates.
			resultCoords=resultCoords.sort(function(a,b){return twUtil.fields(srcCoord,a)-twUtil.fields(srcCoord,b);});

			fnDisplayOutput();
			$('#dsmCoordCount').text('('+resultCoords.length+')');
		} // fnFindFarms
		// ........................................................................
		function fnCurrentConfig(){
			return{
				barbsOnly:$('#dsmBarbOnly').is(':checked'),
				continents:$.map(($('#dsmContinents').val()||'').match(/\d+/g)||[],function(e){return twUtil.int(e);}),
				minPoints:twUtil.int($('#dsmMinPoints').val()||'-1',10),
				maxPoints:twUtil.int($('#dsmMaxPoints').val()||'-1',10),
				radius:$.trim($('#dsmRadius').val())||'-1',
				players:($.trim($('#dsmPlayers').val())||'').split(','),
				tribes:($.trim($('#dsmTribes').val())||'').split(','),
				bbEncoded:$('#dsmBBEncoded').is(':checked'),
				format:$.trim($('#dsmFormat').val())||'{coord}'
			};
		} // fnCurrentConfig
		// ........................................................................
		function fnLoadConfig(){
			var curConfig=twCache.fetch(script.id+'.config')||{
				barbsOnly:false,
				continents:undefined,
				minPoints:-1,
				maxPoints:-1,
				radius:25,
				players:undefined,
				tribes:undefined,
				bbEncoded:false,
				format:'{coord}'
			};
			
			if(curConfig.players=='*** Coming Soon ***'){
				curConfig.players=undefined;
			}
			
			if(curConfig.tribes=='*** Coming Soon ***'){
				curConfig.tribes=undefined;
			}
			
			$('#dsmBarbOnly').attr('checked',curConfig.barbsOnly);
			$('#dsmContinents').val((curConfig.continents||[]).join(','));
			$('#dsmMRTopLeft').val('000|000');
			$('#dsmMRBottomRight').val('999|999');
			$('#dsmMinPoints').val((curConfig.minPoints>=0)?curConfig.minPoints:'');
			$('#dsmMaxPoints').val((curConfig.maxPoints>=0)?curConfig.maxPoints:'');
			$('#dsmBBEncoded').attr('checked',curConfig.bbEncoded);
			$('#dsmRadius').val((parseFloat(curConfig.radius||'0.0')>0.0)?curConfig.radius:'');
			$('#dsmRadiusCentre').val(win.game_data.village.coord);
			$('#dsmPlayers').val((curConfig.players||[]).join(','));
			$('#dsmTribes').val((curConfig.tribes||[]).join(','));
			$('#dsmFormat').val(curConfig.format||'{coord}');
		} // fnLoadConfig
		// ........................................................................
		function fnSaveConfig(){
			twCache.store(script.id+'.config',fnCurrentConfig());
		} // fnSaveConfig
		// ........................................................................
		function fnDisplayOutput(){
			var isBBEncoded=$('#dsmBBEncoded').is(':checked');
			
			var format=$.trim($('#dsmFormat').val());
			if(format){
				var output='';
			
				$.each(resultCoords,function(i,e){
					var village=detail[e].village;
					var player=detail[e].player;
					var tribe=detail[e].tribe;
					
					if(player&&!player.id){
						player=null;
					}
					
					if(tribe&&!tribe.id){
						tribe=null;
					}
					
					twUtil.debug(JSON.stringify(player)+'<br/>'+JSON.stringify(tribe)+'<br/><br/>');
					
					output+=format
						.replace(/\{coord\}/ig,isBBEncoded?'[coord]'+e+'[/coord]':e)
						.replace(/\{points\}/ig,village.points)
						.replace(/\{name\}/ig,village.name)
						.replace(/\{player\}/ig,player?(isBBEncoded?'[player]'+player.name+'[/player]':player.name):'')
						.replace(/\{tribe\_name\}/ig,tribe?tribe.name:'')
						.replace(/\{tribe\}/ig,tribe?(isBBEncoded?'[ally]'+tribe.tag+'[/ally]':tribe.tag):'')
						.replace(/\{continent\}/ig,village.continent)
					+'\n';
				});
			
				$('#dsmOutput').val(output);
			}
			else{
				$('#dsmOutput').val((isBBEncoded?'[coord]':'')+resultCoords.join(isBBEncoded?'[/coord]\n[coord]':' ')+(isBBEncoded?'[/coord]\n':''));
			}			
		} // fnDisplayOutput
		// ........................................................................
		function fnCheckVillagesDAT(){
			var ageMS=undefined;
			
			var cacheVal=twCache.fetch('villagesDAT');
			if(cacheVal&&$.trim(JSON.stringify(cacheVal))){
				villagesDAT=cacheVal.data;
				ageMS=(new Date()).getTime()-cacheVal.lastRefresh;
			}
			
			if(ageMS!=undefined){
				$('#dsmVillagesDATAge').text(twUtil.formatMS2(ageMS,true));
				if(Math.floor(ageMS/(1000*60*60))>=1){
					$('#dsmRefreshVillagesDAT').show();
				}
				else{
					$('#dsmRefreshVillagesDAT').hide();
				}
			}
			else{
				$('#dsmVillagesDATAge').text('*** NO DATA ***');
				$('#dsmRefreshVillagesDAT').show();
			}
		} // fnCheckVillagesDAT
		// ........................................................................
		function fnCheckPlayersDAT(){
			var ageMS=undefined;
			
			var cacheVal=twCache.fetch('playersDAT');
			if(cacheVal&&$.trim(JSON.stringify(cacheVal))){
				playersDAT=cacheVal.data;
				ageMS=(new Date()).getTime()-cacheVal.lastRefresh;
			}
			
			if(ageMS!=undefined){
				$('#dsmPlayersDATAge').text(twUtil.formatMS2(ageMS,true));
				if(Math.floor(ageMS/(1000*60*60))>=1){
					$('#dsmRefreshPlayersDAT').show();
				}
				else{
					$('#dsmRefreshPlayersDAT').hide();
				}
			}
			else{
				$('#dsmPlayersDATAge').text('*** NO DATA ***');
				$('#dsmRefreshPlayersDAT').show();
			}
		} // fnCheckPlayersDAT
		// ........................................................................
		function fnCheckTribesDAT(){
			var ageMS=undefined;
			
			var cacheVal=twCache.fetch('tribesDAT');
			if(cacheVal&&$.trim(JSON.stringify(cacheVal))){
				tribesDAT=cacheVal.data;
				ageMS=(new Date()).getTime()-cacheVal.lastRefresh;
			}
			
			if(ageMS!=undefined){
				$('#dsmTribesDATAge').text(twUtil.formatMS2(ageMS,true));
				if(Math.floor(ageMS/(1000*60*60))>=1){
					$('#dsmRefreshTribesDAT').show();
				}
				else{
					$('#dsmRefreshTribesDAT').hide();
				}
			}
			else{
				$('#dsmTribesDATAge').text('*** NO DATA ***');
				$('#dsmRefreshTribesDAT').show();
			}
		} // fnCheckTribesDAT
		// ........................................................................
		function fnRefreshVillagesDAT(){
			villagesDAT=twConfig.fetchVillagesDAT(1);
			fnCheckVillagesDAT();
		} // fnRefreshVillagesDAT
		// ........................................................................
		function fnRefreshPlayersDAT(){
			playersDAT=twConfig.fetchPlayersDAT(1);
			fnCheckPlayersDAT();
		} // fnRefreshPlayersDAT
		// ........................................................................
		function fnRefreshTribesDAT(){
			tribesDAT=twConfig.fetchTribesDAT(1);
			fnCheckTribesDAT();
		} // fnRefreshTribesDAT
		// ........................................................................
		function fnInjectGUIControls(){
			if($('#dsmFarmFinderPopup').length>0){
				$('#dsmFarmFinderPopup').show();
			
				return;
			}
		
			$('body').append('\
				<div id="dsmFarmFinderPopup" style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:900;">\
					<div style="background:url(/graphic/background/bg-tile.jpg);opacity:0.8;position:fixed;top:0;left:0;width:100%;height:100%;z-index:5;"></div>\
\
					<div style="position:relative;margin:auto;padding:0;top:120px;width:702px;z-index:10;">\
						<a href="#" onclick="$(\'#dsmFarmFinderPopup\').hide();return false;" style="position:absolute;right:-8px;top:-8px;">\
							<img src="graphic/login_close.png" alt="Close" style="border:none;">\
						</a>\
\
						<div style="width:702px;height:22px;background:url(/graphic/index/sprites.png) no-repeat 0 -79px"></div>\
						<div style="padding:10px 20px;width:662px;height:100%;min-height:80px;background:url(/graphic/index/news_background.png) repeat-y">\
							<h1>'+script.name+' <sup><span style="font-size:small;">v'+script.version.toFixed(2)+'</span></sup><sub><span style="font-weight:bold;font-style:italic;text-decoration:none;font-size:x-small;"><a href="'+script.author.url+'" target="_blank"> بواسطة '+script.author.name+'</a></span></sub></h1>\
							<div style="margin:auto;"><table><tr>\
								<td>\
									<table id="dsmSettings" class="vis">\
										<tr><th style="padding:2px 10px;">الإعدادات</th><th style="padding:2px 10px;">القيمة المدخلة</th></tr>\
										<tr><td style="padding:2px 10px;"><span>البربريات فقط</span></td><td style="padding:2px 10px;align:center;"><input id="dsmBarbOnly" type="checkbox"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span>القارة (القارات)</span></td><td style="padding:2px 10px;align:center;"><input id="dsmContinents"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span>تحديد منطقة البحث</span></td><td style="padding:2px 10px;"><span style="margin-left:0.5em;margin-right:0.5em;">أعلى يسار:</span><input id="dsmMRTopLeft" size="7"/><span style="margin-left:0.5em;margin-right:0.5em;">أسفل يمين:</span><input id="dsmMRBottomRight" size="7"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span>الحد الأدنى من النقاط</span></td><td style="padding:2px 10px;"><input id="dsmMinPoints"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span>الحد الأعلى من النقاط</span></td><td style="padding:2px 10px;"><input id="dsmMaxPoints"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span>دائرة نصف قطرها</span></td><td style="padding:2px 10px;"><input id="dsmRadius" size="3"/><span style="margin-left:0.5em;margin-right:0.5em;">مربع @</span><input id="dsmRadiusCentre" size="7"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span id="dsmPlayersTitle">إسم اللاعب (اللاعبين)</span></td><td style="padding:2px 10px;"><input id="dsmPlayers"/></td></tr>\
										<tr><td style="padding:2px 10px;"><span id="dsmTribesTitle">شعار القبيلة (القبائل)</span></td><td style="padding:2px 10px;"><input id="dsmTribes"/></td></tr>\
										<tr><th><input id="dsmFindFarms" type="button" value="إيجاد المزارع" style="width:100%;"/></th><th style="padding:2px 10px;"><a id="dsmSaveConfig" href="#" style="text-align:right;">حفظ الإعدادات</a></th></tr>\
									</table>\
								</td>\
								<td>\
									<table id="dsmResult" class="vis">\
										<tr><th style="padding:2px 10px;"><span>القيمة المستخرجة</span><div style="float:right;"><span id="dsmCoordCount">(0)</span></div></th></tr>\
										<tr><td style="padding:2px 10px;"><label for="dsmFormat">شكل المخرجات:</label><input id="dsmFormat" type="text" style="width:240px;margin-left:1em;" value="{coord}"/><span id="dsmHint"></span></td></tr>\
										<tr><td style="padding:2px 10px;"><textarea id="dsmOutput" cols="40" rows="12" style="overflow-x:hidden;overflow-y:auto;" onfocus="this.select();"></textarea></td></tr>\
										<tr><th style="padding:2px 10px;"><input id="dsmBBEncoded" type="checkbox"/><label for="dsmBBEncode">أكواد تنسيق النص</label></th></tr>\
									</table>\
								</td>\
							</tr></table></div>\
\
							<span style="font-weight:bold;">آخر تحديث لملفات القرى بالعالم:</span>\
							<span id="dsmVillagesDATAge" style="margin-left:1em;"></span>\
							<a id="dsmRefreshVillagesDAT" href="#" style="margin-left:1em;display:none;">&lt;تحديث الآن&gt; ...</a>\
							<br/>\
							<span style="font-weight:bold;">آخر تحديث لملفات اللاعبين بالعالم:</span>\
							<span id="dsmPlayersDATAge" style="margin-left:1em;"></span>\
							<a id="dsmRefreshPlayersDAT" href="#" style="margin-left:1em;display:none;">&lt;تحديث الآن&gt; ...</a>\
							<br/>\
							<span style="font-weight:bold;">آخر تحديث لملفات القبائل بالعالم:</span>\
							<span id="dsmTribesDATAge" style="margin-left:1em;"></span>\
							<a id="dsmRefreshTribesDAT" href="#" style="margin-left:1em;display:none;">&lt;تحديث الآن&gt; ...</a>\
							<br/>\
							<span style="font-style:italic;color:red;">(ملاحظة: تحميل هذه الملفات يحتاج بعض دقائق...)</span>\
							<br/>\
						</div>\
\
						<div style="width: 702px; height: 22px; background:url(/graphic/index/sprites.png) no-repeat 0 -101px;"></div>\
					</div>\
				</div>\
			');
			
			// Wire up any relevant events.
			$('#dsmBarbOnly').click(function(){fnRefreshControls();});
			$('#dsmFindFarms').click(function(){fnCheckVillagesDAT();fnCheckPlayersDAT();fnCheckTribesDAT();fnFindFarms();});
			$('#dsmSaveConfig').click(function(){fnSaveConfig();});
			$('#dsmBBEncoded').click(function(){fnDisplayOutput();});
			$('#dsmRefreshVillagesDAT').click(function(){fnRefreshVillagesDAT();});
			$('#dsmRefreshPlayersDAT').click(function(){fnRefreshPlayersDAT();});
			$('#dsmRefreshTribesDAT').click(function(){fnRefreshTribesDAT();});
			
			$('#dsmHint').html('{coord} - Village Co-ordinate<br/>{points} - Village Points<br/>{name} - Village Name<br/>{player} - Village Owner<br/>{tribe} - Village Owner Tribe Tag<br/>{tribe_name} - Village Owner Tribe Name<br/>{continent} - Village Continent<br/>');
			$('#dsmHint').css({
				display:'none',
				position:'absolute',
				left:$('#dsmFormat').css('right'),
				width:'300px',
				marginTop:'-4px',
				border:'1px solid #c93',
				padding:'10px 12px',
				backgroundColor:'#ffc'
			});
			$('#dsmFormat').live('focus',function(){$('#dsmHint').css({display:'inline'});});
			$('#dsmFormat').live('blur',function(){$('#dsmHint').css({display:'none'});});

			fnLoadConfig();
			fnRefreshControls();
			fnCheckVillagesDAT();
			fnCheckPlayersDAT();
			fnCheckTribesDAT();
		} // fnInjectGUIControls
		// ........................................................................
		function fnRefreshControls(){
			var state=$('#dsmBarbOnly').is(':checked')?'disabled':'';
			var color=$('#dsmBarbOnly').is(':checked')?'gray':'black';
			
			$('#dsmPlayersTitle').css({color:color});
			$('#dsmPlayers').attr('disabled',state);
			
			$('#dsmTribesTitle').css({color:color});
			$('#dsmTribes').attr('disabled',state);
		} //fnRefreshControls
		// ........................................................................
		function fnBootStrapper(){
			if(!twConfig.hasMinVersion(script.minGameVersion)){
				var msg='This script requires v'+script.minGameVersion.toFixed(2)+' or higher.\nYou are running: v'+twConfig.gameVersion.toFixed(2);
				twUtil.print(msg);
				alert(msg);
				return;
			}
			
			fnInjectGUIControls();
			
/*
			switch(win.game_data.screen){
				case 'report':				
					break;
		
				default:
					var msg='This script must be run from a Report Detail Screen!';
					twUtil.print(msg);
					alert(msg);

					break;
			}
*/
			} // fnBootStrapper
		// ........................................................................
		function fnLoadUtils(){
			if($.twUtil){
				twUtil=$.twUtil();
				twConfig=$.twConfig();
				twCache=$.twCache();
				fnBootStrapper();
			}
			else{
				fnAjax(branch+'jquery.tw.utils.js','GET',{},'script',true,function(){
					twCache=$.twCache();
					twConfig=$.twConfig();
					twUtil=$.twUtil();

					twUtil.debugEnabled(debugEnabled);
					twConfig.printVersion(script);
					
					// Log the User Options.
					twUtil.debug('branch='+branch);
					twUtil.debug('debugEnabled='+debugEnabled);
					
					fnBootStrapper();
				});
			}
		} // fnLoadUtils
		// ........................................................................


		var twUtil;
		var twConfig;
		var twCache;
		fnLoadUtils();	
	}
	catch(objError){
		var errMsg=String(objError.message||objError||'');
		if(errMsg){
			$('body').append('<span>'+errMsg+'</span><br/>');
			alert('Error: '+errMsg);
		}
	}} // fnExecute



	// Append to the jQuery Namespace.
	$.extend({
		'twFarmFinder':fnExecute
	});
})((window.main||self).jQuery);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
